<?php

namespace App\Service;

use App\Model\PushClientid;
use App\Utils\LiveApi;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Context\ApplicationContext;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\Logger\LoggerFactory;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use stdClass;
use function Hyperf\Coroutine\co;
use function Hyperf\Support\env;
use function Hyperf\Support\make;

class PushService
{
    protected LoggerInterface $logger;
    protected Client $client;

    public function __construct(protected ContainerInterface $container)
    {
        try {
            $this->logger = $this->container->get(LoggerFactory::class)->get('push');
            $this->client = $this->container->get(ClientFactory::class)->create();
        } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
        }
    }

    /**
     * 推送
     * @param $userid
     * @param $msg
     * @param $client
     * @return void
     */
    public function push($userid, $msg, $client = null): void
    {
        co(function () use ($userid, $client, $msg) {
            $clientIds = PushClientid::query()->where('userid', $userid)->when(!is_null($client), function ($q) use ($client) {
                $q->where('client', $client);
            })->get()->pluck('clientid')->toArray();
            if (empty($clientIds)) {
                return false;
            }
            $clientIdsChunks = array_chunk($clientIds, 500);
            foreach ($clientIdsChunks as $_clientIds) {
                self::_pushMessage($_clientIds, $msg['title'] ?? '您有一条新消息', $msg['content'] ?? '', $msg['data'], $msg['options'] ?? new stdClass());
            }
            return true;
        });
    }

    /**
     * 推送消息
     * @param $clientIds
     * @param $title
     * @param $content
     * @param $data
     * @param $options
     * @return void
     */
    private function _pushMessage($clientIds, $title, $content, $data = [], $options = new stdClass()): void
    {
        static $pushUrl;
        if (is_null($pushUrl)) {
            $pushUrl = env('PUSH_CLOUD_CALL_URL', '');
        }
        if ($pushUrl === '') {
            return;
        }
        $params = [
            'clientIds' => $clientIds,
            'title' => $title,
            'content' => $content,
            'data' => $data,
            'requestId' => create_randomstr(10),
            'forceNotification' => false,
            'options' => $options
        ];
        try {
            $res = $this->client->post($pushUrl, [
                'body' => new_json_encode($params),
                'headers' => [
                    'Content-Type' => 'application/json;charset=utf-8'
                ]
            ]);
            $this->logger->warning(sprintf('push_ids=(%s) result=%s', implode(',', $clientIds), $res->getBody()));
        } catch (GuzzleException $e) {
            $this->logger->error(sprintf('push_ids=(%s) error=%s', implode(',', $clientIds), $e->getMessage()));
        }
    }
}